package server

import (
	"context"
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"sync"
	"time"

	"gitee.com/yuwenlwl/comsdk/security"
	"github.com/gorilla/mux"
)

// HealthStatus 健康状态
type HealthStatus struct {
	Status    string                 `json:"status"`
	Version   string                 `json:"version"`
	Timestamp string                 `json:"timestamp"`
	Checks    map[string]CheckResult `json:"checks"`
}

// CheckResult 检查结果
type CheckResult struct {
	Status  string `json:"status"`
	Message string `json:"message,omitempty"`
}

// HealthCheck 健康检查函数类型
type HealthCheck func() (bool, string)

// HealthManager 健康检查管理器
type HealthManager struct {
	status      string
	version     string
	checks      map[string]HealthCheck
	checksMutex sync.RWMutex
}

// NewHealthManager 创建健康检查管理器
func NewHealthManager(version string) *HealthManager {
	return &HealthManager{
		status:  "UP",
		version: version,
		checks:  make(map[string]HealthCheck),
	}
}

// RegisterCheck 注册健康检查
func (h *HealthManager) RegisterCheck(name string, check HealthCheck) {
	h.checksMutex.Lock()
	defer h.checksMutex.Unlock()
	h.checks[name] = check
}

// HealthHandler 健康检查处理器
func (h *HealthManager) HealthHandler(w http.ResponseWriter, r *http.Request) {
	h.checksMutex.RLock()
	defer h.checksMutex.RUnlock()

	status := "UP"
	checksResult := make(map[string]CheckResult)

	// 执行所有健康检查
	for name, check := range h.checks {
		ok, message := check()
		checkStatus := "UP"
		if !ok {
			checkStatus = "DOWN"
			status = "DOWN" // 任何一项检查失败，整体状态为DOWN
		}

		checksResult[name] = CheckResult{
			Status:  checkStatus,
			Message: message,
		}
	}

	// 构建健康状态响应
	healthStatus := HealthStatus{
		Status:    status,
		Version:   h.version,
		Timestamp: time.Now().Format(time.RFC3339),
		Checks:    checksResult,
	}

	// 发送JSON响应
	w.Header().Set("Content-Type", "application/json")
	if status != "UP" {
		w.WriteHeader(http.StatusServiceUnavailable)
	}

	json.NewEncoder(w).Encode(healthStatus)
}

// Server 核心服务器
type Server struct {
	Router        *mux.Router
	HealthManager *HealthManager
	Verifier      security.Verifier
	version       string
	server        *http.Server
}

// NewServer 创建新的服务器实例
func NewServer(version string, verifier security.Verifier) *Server {
	r := mux.NewRouter()

	s := &Server{
		Router:        r,
		HealthManager: NewHealthManager(version),
		Verifier:      verifier,
		version:       version,
	}

	// 注册健康检查路由
	r.HandleFunc("/health", s.HealthManager.HealthHandler).Methods("GET")

	return s
}

// Start 启动HTTP服务器
func (s *Server) Start(port string) error {
	addr := fmt.Sprintf(":%s", port)
	s.server = &http.Server{
		Addr:    addr,
		Handler: s.Router,
	}

	// 打印所有注册的路由
	log.Println("=== 已注册的路由 ===")
	printRoutes(s.Router)
	log.Println("===================")
	log.Printf("服务器启动在 %s", addr)

	return s.server.ListenAndServe()
}

// Stop 停止HTTP服务器
func (s *Server) Stop(ctx context.Context) error {
	return s.server.Shutdown(ctx)
}

// GatewayAuthMiddleware API网关验证中间件
func (s *Server) GatewayAuthMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		if s.Verifier != nil {
			isValid, err := s.Verifier.VerifyGatewayRequest(r)
			if err != nil || !isValid {
				log.Printf("请求验证失败: %v", err)
				http.Error(w, "Unauthorized", http.StatusUnauthorized)
				return
			}
		}

		next.ServeHTTP(w, r)
	})
}

// JSONResponse 发送JSON响应
func JSONResponse(w http.ResponseWriter, status int, data interface{}) {
	w.Header().Set("Content-Type", "application/json")
	w.WriteHeader(status)
	json.NewEncoder(w).Encode(data)
}

// ErrorResponse 发送错误响应
func ErrorResponse(w http.ResponseWriter, status int, message string) {
	JSONResponse(w, status, map[string]string{
		"error": message,
	})
}

// 辅助函数：打印所有路由
func printRoutes(r *mux.Router) {
	err := r.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
		pathTemplate, err := route.GetPathTemplate()
		if err != nil {
			return err
		}

		methods, _ := route.GetMethods()
		var routeDesc string
		if len(methods) > 0 {
			routeDesc = fmt.Sprintf("%s", methods[0])
		}

		// 获取路由信息，如果能得到的话
		if _, ok := route.GetHandler().(*mux.Router); ok {
			// 这是一个子路由器
			log.Printf("-> %s - 子路由", pathTemplate)
			return nil
		}

		// 尝试推测路由的用途
		var purpose string
		if pathTemplate == "/health" {
			purpose = "健康检查接口"
		} else if routeDesc == "GET" {
			purpose = "查询接口"
		} else if routeDesc == "POST" {
			purpose = "创建接口"
		} else if routeDesc == "PUT" || routeDesc == "PATCH" {
			purpose = "更新接口"
		} else if routeDesc == "DELETE" {
			purpose = "删除接口"
		} else {
			purpose = "API接口"
		}

		log.Printf("-> %s - %s", pathTemplate, purpose)
		return nil
	})

	if err != nil {
		log.Printf("打印路由失败: %v", err)
	}
}
